package com.sl.core.engine.log.store;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.PageResult;
import com.google.common.collect.Maps;
import com.sl.core.engine.log.store.db.DatabaseProcessLogStore;
import com.sl.core.engine.log.store.domain.bo.ProcessLogListByConditionBO;
import com.sl.core.engine.log.store.domain.dto.LogDetailDTO;
import com.sl.core.engine.log.store.domain.dto.MainLogDTO;
import com.sl.core.engine.log.store.domain.entity.LogDetailDO;
import com.sl.core.engine.log.store.domain.entity.MainLogDO;
import com.sl.core.engine.log.store.file.LocalFileProcessLogStore;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class LoggerStoreFactory {

    public static final LoggerStoreFactory INSTANCE = new LoggerStoreFactory();

    private Map<String, IProcessLogStore> processLogStoreMap = Maps.newConcurrentMap();


    public static final String DEDAULT = "local";

    public LoggerStoreFactory() {
        processLogStoreMap.put("local", new LocalFileProcessLogStore());
    }

    public void initDb(String dbCode){
        processLogStoreMap.put("db", new DatabaseProcessLogStore(dbCode));
    }

    public void startMain(MainLogDO mainLogDO) {
        startMain(mainLogDO, DEDAULT);
    }

    public void startMain(MainLogDO mainLogDO, String logStoreType) {
        if(StrUtil.isBlank(logStoreType)){
            logStoreType = DEDAULT;
        }
        IProcessLogStore iProcessLogStore = processLogStoreMap.get(logStoreType);

        if (ObjectUtil.isNull(iProcessLogStore)) {
            return;
        }
        iProcessLogStore.startMain(mainLogDO);
    }

    public void finishMain(String tid, Date endTime, Integer state) {
        finishMain(tid, endTime, state, DEDAULT);
    }

    public void finishMain(String tid, Date endTime, Integer state, String logStoreType) {
        if(StrUtil.isBlank(logStoreType)){
            logStoreType = DEDAULT;
        }
        IProcessLogStore iProcessLogStore = processLogStoreMap.get(logStoreType);

        if (ObjectUtil.isNull(iProcessLogStore)) {
            return;
        }
        iProcessLogStore.finishMain(tid, endTime, state);

    }

    public void saveDetail(LogDetailDO logDetailDO) {
        saveDetail(logDetailDO, DEDAULT);
    }

    public void saveDetail(LogDetailDO logDetailDO, String logStoreType) {
        if(StrUtil.isBlank(logStoreType)){
            logStoreType = DEDAULT;
        }
        IProcessLogStore iProcessLogStore = processLogStoreMap.get(logStoreType);

        if (ObjectUtil.isNull(iProcessLogStore)) {
            return;
        }
        iProcessLogStore.saveDetail(logDetailDO);

    }

    public List<MainLogDTO> listByCondition(ProcessLogListByConditionBO processLogListByConditionBO) {
        return listByCondition(processLogListByConditionBO, DEDAULT);
    }

    public List<MainLogDTO> listByCondition(ProcessLogListByConditionBO processLogListByConditionBO, String logStoreType) {
        if(StrUtil.isBlank(logStoreType)){
            logStoreType = DEDAULT;
        }
        IProcessLogStore iProcessLogStore = processLogStoreMap.get(logStoreType);

        if (ObjectUtil.isNull(iProcessLogStore)) {
            return new PageResult<>();
        }
        List<MainLogDTO> mainLogDTOS = iProcessLogStore.listByCondition(processLogListByConditionBO);
        return mainLogDTOS;
    }

    public List<LogDetailDTO> getDetailByTid(String tid, Date logTime) {
        return getDetailByTid(tid, logTime,DEDAULT);
    }

    public List<LogDetailDTO> getDetailByTid(String tid, Date logTime, String logStoreType) {
        if(StrUtil.isBlank(logStoreType)){
            logStoreType = DEDAULT;
        }
        IProcessLogStore iProcessLogStore = processLogStoreMap.get(logStoreType);

        if (ObjectUtil.isNull(iProcessLogStore)) {
            return Collections.emptyList();
        }
        List<LogDetailDTO> detailByTid = iProcessLogStore.getDetailByTid(tid, logTime);
        return detailByTid;
    }

    public Boolean updateStateById(String id, Integer state) {
        return updateStateById(id, state, DEDAULT);
    }

    public Boolean updateStateById(String id, Integer state, String logStoreType) {
        if(StrUtil.isBlank(logStoreType)){
            logStoreType = DEDAULT;
        }
        IProcessLogStore iProcessLogStore = processLogStoreMap.get(logStoreType);

        if (ObjectUtil.isNull(iProcessLogStore)) {
            return Boolean.FALSE;
        }
        Boolean result = iProcessLogStore.updateStateById(id, state);
        return result;
    }

    public MainLogDTO getMainByTid(String tid,Date logTime,String logStoreType) {
        if(StrUtil.isBlank(logStoreType)){
            logStoreType = DEDAULT;
        }
        IProcessLogStore iProcessLogStore = processLogStoreMap.get(logStoreType);

        if (ObjectUtil.isNull(iProcessLogStore)) {
            return null;
        }
        MainLogDTO result = iProcessLogStore.getMainByTid(tid,logTime);
        return result;
    }
}
